package org.erp.product.infrastructure.config;

import org.erp.product.infrastructure.enums.InspectionEventEnum;
import org.erp.product.infrastructure.enums.InspectionStatusEnum;

import java.util.HashMap;
import java.util.Map;

public class InspectionStateFlow {

    private static final Map<InspectionStatusEnum, Map<InspectionEventEnum, InspectionStatusEnum>> FLOW = new HashMap<>();

    static {
        register(InspectionStatusEnum.WAITING_INSPECTION, InspectionEventEnum.QUALITY, InspectionStatusEnum.QUALIFIED);
        register(InspectionStatusEnum.WAITING_INSPECTION, InspectionEventEnum.TRANSFER, InspectionStatusEnum.TRANSFERRING);
        register(InspectionStatusEnum.WAITING_INSPECTION, InspectionEventEnum.RETURN_BACK, InspectionStatusEnum.WAITING_RECYCLE);
        register(InspectionStatusEnum.QUALIFIED, InspectionEventEnum.ON_SHELF, InspectionStatusEnum.ON_SHELF);
        register(InspectionStatusEnum.QUALIFIED, InspectionEventEnum.TRANSFER, InspectionStatusEnum.TRANSFERRING);
        register(InspectionStatusEnum.QUALIFIED, InspectionEventEnum.RETURN_BACK, InspectionStatusEnum.WAITING_RECYCLE);
        register(InspectionStatusEnum.ON_SHELF, InspectionEventEnum.OFF_SHELF, InspectionStatusEnum.OFF_SHELF);
        register(InspectionStatusEnum.OFF_SHELF, InspectionEventEnum.ON_SHELF, InspectionStatusEnum.ON_SHELF);
        register(InspectionStatusEnum.OFF_SHELF, InspectionEventEnum.TRANSFER, InspectionStatusEnum.TRANSFERRING);
        register(InspectionStatusEnum.OFF_SHELF, InspectionEventEnum.RETURN_BACK, InspectionStatusEnum.WAITING_RECYCLE);
        register(InspectionStatusEnum.TRANSFERRING, InspectionEventEnum.SELL_CONNECT, InspectionStatusEnum.QUALIFIED);
        register(InspectionStatusEnum.TRANSFERRING, InspectionEventEnum.INSPECTION_DICKER_CONNECT, InspectionStatusEnum.WAITING_INSPECTION);
        register(InspectionStatusEnum.TRANSFERRING, InspectionEventEnum.REPAIR_CONNECT, InspectionStatusEnum.CONNECTED);
        register(InspectionStatusEnum.TRANSFERRING, InspectionEventEnum.INSPECTION_DICKER_OVERRULE, InspectionStatusEnum.WAITING_INSPECTION);
        register(InspectionStatusEnum.TRANSFERRING, InspectionEventEnum.SELL_OVERRULE, InspectionStatusEnum.QUALIFIED);
        register(InspectionStatusEnum.CONNECTED, InspectionEventEnum.INSPECTION_DICKER_CONNECT, InspectionStatusEnum.WAITING_INSPECTION);
        register(InspectionStatusEnum.CONNECTED, InspectionEventEnum.SELL_CONNECT, InspectionStatusEnum.QUALIFIED);
        register(InspectionStatusEnum.WAITING_RECYCLE, InspectionEventEnum.CONFIRM_RETURN, InspectionStatusEnum.RECYCLED);
    }

    private static void register(InspectionStatusEnum source, InspectionEventEnum event, InspectionStatusEnum target) {
        FLOW.computeIfAbsent(source, k -> new HashMap<>()).put(event, target);
    }

    public static InspectionStatusEnum next(InspectionStatusEnum current, InspectionEventEnum event) {
        Map<InspectionEventEnum, InspectionStatusEnum> eventMap = FLOW.get(current);
        if (eventMap == null) {
            throw new IllegalStateException("质检状态不允许执行任何事件: " + current);
        }
        InspectionStatusEnum next = eventMap.get(event);
        if (next == null) {
            throw new IllegalStateException("质检状态 " + current + " 不支持事件 " + event);
        }
        return next;
    }
}
